package com.fsh.lingsp.common.user.service.impl;

import com.fsh.lingsp.common.common.domain.enums.YseOrNoEnum;
import com.fsh.lingsp.common.common.service.LockService;
import com.fsh.lingsp.common.user.dao.UserBackpackDao;
import com.fsh.lingsp.common.user.domain.entity.UserBackpack;
import com.fsh.lingsp.common.user.domain.enums.IdempotentEnum;
import com.fsh.lingsp.common.user.service.UserBackpackService;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class UserBackpackServiceImpl implements UserBackpackService {

    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private UserBackpackDao userBackpackDao;
    @Autowired
    private LockService lockService;

    /**
     * 用户获取一个物品。考虑幂等，并使用分布式锁。（todo 改成注解）
     *
     * @param uid            用户id
     * @param itemId         物品id
     * @param idempotentEnum 幂等类型
     * @param businessId     上层业务发送的唯一标识
     */
    @Override
    public void acquireItem(Long uid, Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        // 调用方法 ，获取幂等key
        String idempotent=getIdempotent(itemId,idempotentEnum,businessId);
        // 使用工具类，上锁
        lockService.executeWithLock("acquireItem" + idempotent,()->{
            //先根据幂等号查看数据库中该用户的背包表有没有 这个物品
            UserBackpack userBackpack =userBackpackDao.getByIdempotent(idempotent);
            if (Objects.nonNull(userBackpack)){
                // 这个幂等号，已经存在了。代表已经获得物品了，直接返回
                return;
            }
            //发放物品
            UserBackpack userBackpack1=UserBackpack.builder()
                    .uid(uid)
                    .itemId(itemId)
                    .status(YseOrNoEnum.NO.getStatus())
                    .idempotent(idempotent)
                    .build();
            userBackpackDao.save(userBackpack1);
        });
    }

    // 根据传入的参数，构建幂等key
    private String getIdempotent(Long itemId, IdempotentEnum idempotentEnum, String businessId) {
        return String.format("%d_%d_%s",itemId,idempotentEnum.getType(),businessId);
    }

}
